﻿#ifndef TempObstaclesNavMesh_h__
#define TempObstaclesNavMesh_h__
#include "../Detour/DetourNavMesh.h"
#include "../Detour/DetourNavMeshQuery.h"
#include "../DetourTileCache/Include/DetourTileCache.h"
#include "TileCacheOther.h"
//#include <Finder/PathFinder.h>
//#include <Detour/DetourNavMesh.h>
//#include <Detour/DetourNavMeshQuery.h>
//#include <DetourTileCache/Include/DetourTileCache.h>
//#include <Finder/TileCacheOther.h>
#include <string.h>
#include <string>
#include <map>
#include <vector>
#include <fstream>

//class dtNavMesh;
//class dtTileCache;
//class dtNavMeshQuery;
//struct dtTileCacheAlloc;
//struct dtTileCacheCompressor;
//struct dtTileCacheMeshProcess;

//#define OUTPUT_DEBUG 

class TempObstaclesNavMesh
{
	dtNavMesh* m_navMesh = { nullptr };
	dtNavMeshQuery* m_navQuery = { nullptr };
	dtQueryFilter m_filter;
	float m_polyPickExt[3];

	static const int MAX_POLYS = 256;

	float m_spos[3] = {0.0f};
	float m_epos[3] = {0.0f};
	dtPolyRef m_startRef = {0};
	dtPolyRef m_endRef = {0};
	dtPolyRef m_polys[MAX_POLYS] = {0};
	dtPolyRef m_parent[MAX_POLYS] = {0};
	int m_npolys = {0};
	float m_Path[MAX_POLYS * 3] = {0.0f};
	unsigned char m_PathFlags[MAX_POLYS] = {0};
	dtPolyRef m_PathPolys[MAX_POLYS] = {0};
	int m_nstraightPath = {0};

	///////////TmpObstacle///////////
	dtTileCacheAlloc* m_talloc = { nullptr };
	dtTileCacheCompressor* m_tcomp = { nullptr };
	dtTileCacheMeshProcess* m_tmproc = { nullptr };
	dtTileCache* m_tileCache = { nullptr };

	// 按照名称保存当前的动态阻挡
	std::map<std::string, std::vector<dtObstacleRef>> m_mapTag2TO;

	int m_nearCount = { 0 };
	float m_nearPos[3] = { 0,0,0 };

	float m_hitPos[3] = {0,0,0};
	int m_hitCount = {0};
	bool m_hitResult = { false };
public:
	TempObstaclesNavMesh();
	TempObstaclesNavMesh(const TempObstaclesNavMesh& o) = delete;
	~TempObstaclesNavMesh();
	TempObstaclesNavMesh& operator=(const TempObstaclesNavMesh& o) = delete;
	bool LoadMeshFile(std::string file_name);
	bool LoadNavMesh(std::string file_name);
	void FindPath(float sp[3], float ep[3]);
	void Update();
	void AddCylinderTO(std::string tag, float& posX, float& posY, float& posZ, float& radius, float& height);
	void AddObbBox(std::string tag, float& centX, float& centY, float& centZ, float& halfX, float& halfY, float& halfZ, float& rotaY);
	void AddAabbBox(std::string tag, float& minX, float& minY, float& minZ, float& maxX, float& maxY, float& maxZ);
	void AddObstacle(float* p);
	void AddBoxObstacle(float minPos[3], float maxPos[3]);
	void RemoveOneObstacle(int idx);
	void RemoveAllObstacle();
	void RemoveTOByTag(std::string tag);
	void RemoveAllTO();

	bool Find(float& sposX, float& sposY, float& sposZ, float& eposX, float& eposY, float& eposZ);
	float* GetPath(int* count);
	bool CalcNear(float& sposX, float& sposY, float& sposZ);
	float* GetNear(int* count);
	bool CalcRaycast(float& sposX, float& sposY, float& sposZ, float& eposX, float& eposY, float& eposZ);
	float* GetRaycast(int* count);
protected:
	void Reset();
#ifdef OUTPUT_DEBUG
	std::ofstream ofs;
#endif
};

#endif // TempObstaclesNavMesh_h__
